\section{Our technique}

As permitted by the \commonlisp{} standard, the \texttt{defgeneric}
macro may store information provided in the \texttt{defgeneric} form
so as to make better error reporting possible when subsequent forms
are compiled.  In particular, the standard mentions storing
information about the lambda list given, so that subsequent calls to
the generic function can be checked for correct argument count.
This information is kept in an implementation-specific format that
does not contain the full generic-function metaobject, as this object
is created when the compiled code resulting from the file compilation
is loaded.

However, just as it is possible to keep information about the lambda
list at compile time, it is also possible to keep information about
the \texttt{:method-class} option given, or, when no option was
supplied, the fact that the method class is \texttt{standard-method}.

With this additional information, during the expansion of the
\texttt{defmethod} macro, the name of the method class can be
retrieved, then a class metaobject from the name, and finally a class
prototype from the class metaobject.

While the first parameter of \mml{} is indicated by the AMOP book as a
generic-function metaobject, it is not specifically indicated that
this object might be uninitialized, contrary to the method object that
must be passed as the second argument.  It is, however, indicated that
the generic-function object passed as the first argument may not be
the generic-function object to which the new method will eventually be
added.  Therefore, there is not much information that \mml{} can make
use of.  The exception would be the exact class of the generic
function and the exact method class.  It would be awkward for a method
on \mml{} to access this information explicitly, rather than as
specializers of its parameters.  For that reason, the first argument
to \mml{} might as well be a class prototype, just as the second
argument might be.

As an example of how to accomplish this additional information, we
suggest a solution with two parts:

\begin{enumerate}
\item The first part involves the possibility for the compiler to
  store information about a generic function in the compilation
  environment, as the result of compiling a \texttt{defgeneric} form.
  Specifically, the name of the generic-function class and the name of
  the method class would need to be stored, and later retrieved.
\item The second part requires a modification to the protocol used by
  the compiler to query the compilation environment in order to
  determine how a form is to be compiled.
\end{enumerate}

For a solution to the first part, in \refApp{app-protocol} we show how
additional information about a generic function can be stored and
retrieved in the context of the protocol described in Strandh's paper
on first-class global environments
\cite{Strandh:2015:ELS:Environments}.

For the second part, recall that in section 8.5 of the second edition
of Guy Steele's book on \commonlisp{} \cite{Steele:1990:CLL:95411},
the author describes a protocol for this kind of environment query.
This protocol contains three functions for environment query, namely
\texttt{function-information}, \texttt{variable-information}
and \texttt{declaration-information}.

Not only are these functions inadequate for all the information that a
compiler needs to determine about a function or a variable, but they
are also hard to extend in a backward-compatible way.  A modern
version of this protocol would likely return standard objects as
opposed to multiple values, thereby allowing for backward-compatible
extensions on a per-implementation basis.

For the second part of our solution, the environment function
\texttt{function-information}, when given the name that has previously
been encountered in a \texttt{defgeneric} form, would have to return
information about the name of the generic-function class and the
method class.  With this additional information, the expander for the
macro \texttt{defmethod} would query the environment for this
information, access the corresponding classes, and then the class
prototypes, and finally call \mml{} with those prototypes as
arguments.

While our solution is an improvement on the existing situation, it is
clearly not perfect.  For one thing, both the generic-function class
and the method class mentioned in the \texttt{defgeneric} form must
exist when the \texttt{defmethod} form is encountered, so that the
class prototypes of these classes can be passed as arguments to \mml{}.

Also, when a custom generic-function class is used, it is possible
that there exist custom methods on various generic functions for
initializing instances of this custom class, and these custom methods
could conceivably intercept and alter the method class in the
generic-function metaobject thus created.  In such a situation, our
technique would then use incorrect information about the method class,
and pass the wrong class prototype as the second argument to \mml{}.
